﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
using CPAScoringPerformanceTester.Models;
using System.Diagnostics;
using CPAScoringPerformanceTester.TestTask;

namespace CPAScoringPerformanceTester.Windows
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private TestTaskItem selectedTaskType;
        private bool stopped = true;
        public event PropertyChangedEventHandler PropertyChanged;

        #region Properties
        public ObservableCollection<Robot> Robots { get; set; }

        #region ToolBars
        private bool toolBarVisible;
        public bool ToolBarVisible
        {
            get { return toolBarVisible; }
            set
            {
                toolBarVisible = value;
                OnPropertyChanged("ToolBarVisible");
            }
        }

        private bool runEnabled;
        public bool RunEnabled
        {
            get { return runEnabled; }
            set
            {
                runEnabled = value;

                OnPropertyChanged("RunEnabled");
                OnPropertyChanged("RunImage");
            }
        }
        public string RunImage
        {
            get
            {
                return RunEnabled ? "../Images/run.png" : "../Images/run_grey.png";
            }
        }

        private bool stopEnabled;
        public bool StopEnabled
        {
            get { return stopEnabled; }
            set
            {
                stopEnabled = value;
                OnPropertyChanged("StopEnabled");
                OnPropertyChanged("StopImage");
            }
        }
        public string StopImage
        {
            get
            {
                return StopEnabled ? "../Images/stop.png" : "../Images/stop_grey.png";
            }
        }
        #endregion

        #region Statistics
        public int SuccessCount
        {
            get
            {
                return Robots.Sum(m => m.SuccessCount);
            }
        }

        public int FailureCount
        {
            get
            {
                return Robots.Sum(m => m.FailureCount);
            }
        }

        public int TotalCount
        {
            get
            {
                return Robots.Sum(m => m.TotalCount);
            }
        }

        public int PendingCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Pending);
            }
        }

        public int RunningCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Running);
            }
        }

        public int SettingCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Setting);
            }
        }

        public int StoppedCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Stopped);
            }
        }

        public int CompletedCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Completed);
            }
        }

        public int ErrorCount
        {
            get
            {
                return Robots.Count(m => m.Status == RobotStatus.Error);
            }
        }
        #endregion

        #region Commands
        public RelayCommand SaveCommand { get; set; }
        public RelayCommand SaveAsCommand { get; set; }
        public RelayCommand AddRobotCommand { get; set; }
        public RelayCommand RemoveAllRobotsCommand { get; set; }
        public RelayCommand SelectTaskCommand { get; set; }
        public RelayCommand OptionsCommand { get; set; }
        public RelayCommand RunCommand { get; set; }
        public RelayCommand StopCommand { get; set; }
        public RelayCommand ResetCommand { get; set; }
        public RelayCommand ReportCommand { get; set; }
        public RelayCommand PreferenceCommand { get; set; }
        public RelayCommand AboutCommand { get; set; }
        public RelayCommand ServiceConnectionCommand { get; set; }
        public RelayCommand UserLoginCommand { get; set; }
        public RelayCommand ScoreTaskListCommand { get; set; }
        public RelayCommand ScoreTaskDetailCommand { get; set; }
        public RelayCommand ScoreTaskPaperItemsCommand { get; set; }
        public RelayCommand ScoreTaskApplyCommand { get; set; }
        public RelayCommand ScoreTaskRecordCommand { get; set; }
        public RelayCommand ScoreTaskSaveCommand { get; set; }
        public RelayCommand ScoreTaskSubmitCommand { get; set; }
        #endregion
        #endregion

        public MainWindow()
        {
            Robots = new ObservableCollection<Robot>();
            SaveCommand = new RelayCommand(Save, param => this.stopped);
            SaveAsCommand = new RelayCommand(SaveAs, param => this.stopped);
            AddRobotCommand = new RelayCommand(AddRobot, param => this.stopped);
            RemoveAllRobotsCommand = new RelayCommand(() =>
            {
                Robots.Clear();
                RunEnabled = false;
            }, param => this.stopped);
            SelectTaskCommand = new RelayCommand(SelectTask, param => this.stopped);
            OptionsCommand = new RelayCommand(() =>
            {
                OptionsWindow optionsWindow = new OptionsWindow();
                optionsWindow.Owner = this;
                optionsWindow.ShowDialog();
            }, param => this.stopped);
            RunCommand = new RelayCommand(Run, param => this.RunEnabled);
            StopCommand = new RelayCommand(Stop, param => this.StopEnabled);
            ResetCommand = new RelayCommand(Reset, param => this.RunEnabled);
            PreferenceCommand = new RelayCommand(() =>
            {
                PreferenceWindow win = new PreferenceWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ReportCommand = new RelayCommand(() =>
            {
                var win = new ReportWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            AboutCommand = new RelayCommand(() =>
            {
                AboutWindow win = new AboutWindow();
                win.Owner = this;
                win.ShowDialog();
            });
            ServiceConnectionCommand = new RelayCommand(() =>
            {
                var win = new ServiceConnectionTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            UserLoginCommand = new RelayCommand(() =>
            {
                var win = new UserLoginWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskListCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskListTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskDetailCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskDetailTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskPaperItemsCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskPaperItemsTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskApplyCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskApplyTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskRecordCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskRecordTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskSaveCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskSaveTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);
            ScoreTaskSubmitCommand = new RelayCommand(() =>
            {
                var win = new ScoreTaskSubmitTaskWindow();
                win.Owner = this;
                win.ShowDialog();
            }, param => this.stopped);

            InitializeComponent();
            this.Closing += (sender, e) =>
            {
                if (StopEnabled) this.Stop();
            };
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void Save()
        {
            Debug.WriteLine("Save");
        }

        private void SaveAs()
        {
            Debug.WriteLine("SaveAs");
        }

        private void AddRobot()
        {
            RobotWindow robotWindow = new RobotWindow();
            robotWindow.Owner = this;
            robotWindow.RobotAdded += (obj, args) =>
            {
                if (args.NewRobots.Count > 0) RunEnabled = true;
                foreach (var item in args.NewRobots)
                {
                    this.Robots.Add(item);
                    item.RobotStatusChanged += new RobotStatusChangedEventHandler((x, e) =>
                    {
                        UpdateStatus(e.NewStatus);
                    });
                    item.ExecutionCompleted += new ExecutionCompletedEventHandler((x, e) =>
                    {
                        OnPropertyChanged("TotalCount");
                        OnPropertyChanged("SuccessCount");
                        OnPropertyChanged("FailureCount");
                    });
                    item.SetTask(selectedTaskType);
                }
            };
            robotWindow.ShowDialog();
        }

        private void UpdateStatus(RobotStatus status)
        {
            OnPropertyChanged("PendingCount");
            OnPropertyChanged("SettingCount");
            OnPropertyChanged("RunningCount");
            OnPropertyChanged("StoppedCount");
            OnPropertyChanged("CompletedCount");
            OnPropertyChanged("ErrorCount");

            if (Robots.Count(m => m.Status == RobotStatus.Setting || m.Status == RobotStatus.Running) <= 0)
            {
                RunEnabled = true;
                stopped = true;
            }
        }

        private void SelectTask()
        {
            TaskWindow win = new TaskWindow(selectedTaskType);
            win.Owner = this;
            win.TaskSelected += (sender, args) =>
            {
                selectedTaskType = args.SelectedTaskType;
                foreach (var item in Robots)
                {
                    item.SetTask(selectedTaskType);
                }
            };
            win.ShowDialog();
        }

        private void Run()
        {
            stopped = false;
            RunEnabled = false;
            StopEnabled = true;

            foreach (var item in Robots)
            {
                item.SetUp();
                item.Run();
            }
        }

        private void Stop()
        {
            StopEnabled = false;

            foreach (var item in Robots)
            {
                item.Stop();
            }
        }

        private void Reset()
        {
            foreach (var item in Robots)
            {
                item.Reset();
            }
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }
    }
}
